package com.cloud.school.app.service.impl;

import com.cloud.school.app.entity.TbAnswer;
import com.cloud.school.app.mapstruct.IAnswerConvertMapper;
import com.cloud.school.app.model.AnswerModel;
import com.cloud.school.app.model.ImageModel;
import com.cloud.school.app.model.QuestionModel;
import com.cloud.school.app.model.UserModel;
import com.cloud.school.app.repository.TbAnswerMapper;
import com.cloud.school.app.service.AnswerService;
import com.cloud.school.app.service.ImageService;
import com.cloud.school.app.service.QuestionService;
import com.cloud.school.app.service.UserService;
import com.cloud.school.app.util.IdWorker;
import com.cloud.school.app.util.exception.SystemHandleException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName AnswerServiceImpl
 * @Description TODO
 * @Author 36297
 * @Date 2018/12/14 0:51
 * @Version 1.0
 */
@Service
public class AnswerServiceImpl implements AnswerService {
    public static final String USER_NEW_ANSWER = "newAnswer.userId";

    @Autowired
    private TbAnswerMapper tbAnswerMapper;
    @Autowired
    private IAnswerConvertMapper answerConvertMapper;
    @Autowired
    private IdWorker answerIdWorker;
    @Autowired
    private ImageService imageService;
    @Autowired
    private UserService userService;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private QuestionService questionService;

    @Override
    public List<AnswerModel> queryByQuestionId(Long questionId) {
        TbAnswer answer = new TbAnswer();
        answer.setQuestionId(questionId);
        List<AnswerModel> result = answerConvertMapper.entityToModel(tbAnswerMapper.select(answer));
        appendImage(result);
        return result;
    }

    @Override
    public List<AnswerModel> queryByQuestionIds(List<Long> questionIds) {
        questionIds = questionIds.stream().distinct().collect(Collectors.toList());
        Example example = new Example(TbAnswer.class);
        example.createCriteria().andIn("questionId", questionIds);
        return answerConvertMapper.entityToModel(tbAnswerMapper.selectByExample(example));

    }

    @Override
    public List<AnswerModel> queryDetailByQuestionIds(List<Long> questionIds) {
        List<AnswerModel> result = queryByQuestionIds(questionIds);
        appendUser(result);
        appendImage(result);
        return result;
    }

    private void appendUser(List<AnswerModel> result) {
        List<Long> uids = result.stream().map(a -> a.getCreateUid()).filter(id -> id != null).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(uids)) {
            Map<Long, UserModel> userModelMap = userService.queryDetailByIds(uids).stream().collect(Collectors.toMap(UserModel::getId, u -> u));
            result.forEach(a -> a.setCreator(userModelMap.get(a.getCreateUid())));
        }
    }

    private void appendImage(List<AnswerModel> result) {
        List<Long> imageIds = result.stream().map(s -> s.getImages()).flatMap(images -> images.stream()).filter(id -> id != null).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(imageIds)) {
            Map<Long, ImageModel> imageModelMap = imageService.seleteByIds(imageIds).stream().collect(Collectors.toMap(ImageModel::getId, i -> i));
            result.forEach(a -> a.setImageModels(getByIdsString(imageModelMap, a.getImages())));
        }
    }

    private List<ImageModel> getByIdsString(Map<Long, ImageModel> imageModelMap, List<Long> ids) {
        List<ImageModel> list = Lists.newArrayList();
        ids.forEach(id -> list.add(imageModelMap.get(id)));
        return list;
    }

    @Override
    @Transactional
    public boolean save(AnswerModel answerModel) {
        if (answerModel.getPrevId() != null && tbAnswerMapper.selectByPrimaryKey(answerModel.getPrevId()) == null) {
            throw new SystemHandleException("上一回答不存在!");
        }
        TbAnswer answer = answerConvertMapper.modelToEntity(answerModel);
        answer.setId(answerIdWorker.nextId());
        QuestionModel questionModel = questionService.selectById(answerModel.getQuestionId());
        cacheService.hashIncr(USER_NEW_ANSWER + questionModel.getCreateUid(), String.valueOf(questionModel.getId()));
        answer.setCreateTime(System.currentTimeMillis());
        return tbAnswerMapper.insertSelective(answer) > 0;
    }

    @Override
    public Map<Long, Long> selectCountGroupByQuestionIdIn(List<Long> questionIds) {
        List<Map<Long, Long>> rs = tbAnswerMapper.selectCountGroupByQuestionIdIn(questionIds);
        Map<Long, Long> result = Maps.newHashMap();
        rs.forEach(m -> result.put(m.get("question_id"), m.get("answer_num")));
        return result;
    }

    @Override
    @Transactional
    public boolean deleteByQuestionId(Long questionId) {
        TbAnswer answer = new TbAnswer();
        answer.setQuestionId(questionId);
        List<AnswerModel> result = answerConvertMapper.entityToModel(tbAnswerMapper.select(answer));
        List<Long> imageIds = result.stream().map(s -> s.getImages()).flatMap(images -> images.stream()).filter(id -> id != null).collect(Collectors.toList());
        imageIds.forEach(id -> imageService.delete(id));
        return tbAnswerMapper.delete(answer) > 0;
    }
}
